package de.hub.emffrag.fragmentation; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EDataType; import org.eclipse.emf.ecore.EEnum; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.InternalEObject; import org.eclipse.emf.ecore.InternalEObject.EStore; import org.eclipse.emf.ecore.impl.DynamicEObjectImpl; import org.eclipse.emf.ecore.util.EcoreUtil; import de.hub.emffrag.EmfFragActivator; public class FStoreImpl implements EStore { private static FStoreImpl instance = new FStoreImpl(); public static FStoreImpl getInstance() { return instance; } private Object getUserValue(Object internalValue, EStructuralFeature userFeature) { if (userFeature != null && userFeature.getEType() instanceof EEnum) { return EcoreUtil.createFromString((EDataType) userFeature.getEType(), internalValue.toString()); } else if (internalValue != null && internalValue instanceof DynamicEObjectImpl) { FInternalObjectImpl internalObject = (FInternalObjectImpl) internalValue; return getUserObject(internalObject); } else { return internalValue; } } public EObject getUserObject(FInternalObjectImpl internalObject) { return internalObject.getUserObject(); } public FInternalObjectImpl getInternalObject(EObject userObject) { FInternalObjectImpl internalObject = ((FObjectImpl) userObject).fInternalObject(); if (internalObject == null) { // This object was not yet added to a model internalObject = UserObjectsCache.instance.createInternalObject((FObjectImpl)userObject); } else if (internalObject.eIsProxy()) { FragmentedModel model = internalObject.getFragmentation(); if (model == null) { model = ((FObjectImpl)userObject).fFragmentation(); } if (model == null) { model = EmfFragActivator.instance.defaultModel; } if (model != null) { internalObject = (FInternalObjectImpl)EcoreUtil.resolve(internalObject, model.getInternalResourceSet()); if (internalObject.eIsProxy()) { // try a second time ... no idea why first time fails from time to time if (internalObject.eProxyURI().toString().endsWith("10000")) { internalObject = (FInternalObjectImpl)EcoreUtil.resolve(internalObject, model.getInternalResourceSet()); } internalObject = (FInternalObjectImpl)EcoreUtil.resolve(internalObject, model.getInternalResourceSet()); if (internalObject.eIsProxy()) { throw new RuntimeException("Could not resolve " + internalObject.eProxyURI()); } } } else { throw new NotInAFragmentedModelException("An user object that appreas to be new is a proxy."); } } return internalObject; } private EStructuralFeature getInternalFeature(EStructuralFeature feature) { return ReflectiveMetaModelRegistry.instance.getInternalFeature(feature); } private Object getInternalValue(Object userValue, EStructuralFeature internalFeature) { EClassifier eType = internalFeature.getEType(); if (eType instanceof EEnum) { return eType.getEPackage().getEFactoryInstance().createFromString((EDataType)eType, userValue.toString()); } else if (userValue != null && userValue instanceof FObjectImpl) { return getInternalObject((InternalEObject) userValue); } else { return userValue; } } @Override public Object get(InternalEObject object, EStructuralFeature feature, int index) { feature = getInternalFeature(feature); EObject internalObject = getInternalObject(object); if (feature.isMany()) { return getUserValue(((EList<?>) internalObject.eGet(feature)).get(index), feature); } else { return getUserValue(internalObject.eGet(feature), feature); } } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public Object set(InternalEObject object, EStructuralFeature feature, int index, Object value) { FInternalObjectImpl internalObject = getInternalObject(object); feature = getInternalFeature(feature); Object internalValue = getInternalValue(value, feature); Object result = null; boolean valueIsProtected = false; if (internalValue instanceof FInternalObjectImpl) { valueIsProtected = protect((FInternalObjectImpl)internalValue); } protect(internalObject); if (feature.isMany()) { result = getUserValue(((EList) internalObject.eGet(feature)).set(index, internalValue), feature); } else { Object oldValue = getUserValue(internalObject.eGet(feature), feature); internalObject.eSet(feature, internalValue); result = oldValue; } if (feature instanceof EReference && internalValue != null && !((EReference) feature).isContainment()) { EmfFragActivator.instance.idSemantics.onObjectAsReferenced((FInternalObjectImpl)internalObject); } unprotect(internalObject); if (valueIsProtected) { unprotect((FInternalObjectImpl)internalValue); } return result; } @Override public boolean isSet(InternalEObject object, EStructuralFeature feature) { feature = getInternalFeature(feature); return getInternalObject(object).eIsSet(feature); } @Override public void unset(InternalEObject object, EStructuralFeature feature) { feature = getInternalFeature(feature); FInternalObjectImpl internalObject = getInternalObject(object); protect(internalObject); internalObject.eUnset(feature); unprotect(internalObject); } @Override public boolean isEmpty(InternalEObject object, EStructuralFeature feature) { feature = getInternalFeature(feature); return ((EList<?>) getInternalObject(object).eGet(feature)).isEmpty(); } @Override public int size(InternalEObject object, EStructuralFeature feature) { feature = getInternalFeature(feature); return ((EList<?>) getInternalObject(object).eGet(feature)).size(); } @SuppressWarnings("rawtypes") @Override public boolean contains(InternalEObject object, EStructuralFeature feature, Object value) { feature = getInternalFeature(feature); return ((EList) getInternalObject(object).eGet(feature)).contains(getInternalValue(value, feature)); } @SuppressWarnings("rawtypes") @Override public int indexOf(InternalEObject object, EStructuralFeature feature, Object value) { feature = getInternalFeature(feature); return ((EList) getInternalObject(object).eGet(feature)).indexOf(getInternalValue(value, feature)); } @SuppressWarnings("rawtypes") @Override public int lastIndexOf(InternalEObject object, EStructuralFeature feature, Object value) { feature = getInternalFeature(feature); return ((EList) getInternalObject(object).eGet(feature)).lastIndexOf(getInternalValue(value, feature)); } @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public void add(InternalEObject object, EStructuralFeature feature, int index, Object value) { feature = getInternalFeature(feature); Object internalValue = getInternalValue(value, feature); FInternalObjectImpl internalObject = getInternalObject(object); boolean valueIsProtected = false; if (internalValue instanceof FInternalObjectImpl) { valueIsProtected = protect((FInternalObjectImpl)internalValue); } protect(internalObject); ((EList) internalObject.eGet(feature)).add(index, internalValue); if (feature instanceof EReference && !((EReference) feature).isContainment()) { EmfFragActivator.instance.idSemantics.onObjectAsReferenced((FInternalObjectImpl)internalValue); } unprotect(internalObject); if (valueIsProtected) { unprotect((FInternalObjectImpl)internalValue); } } @Override public Object remove(InternalEObject object, EStructuralFeature feature, int index) { feature = getInternalFeature(feature); FInternalObjectImpl internalObject = getInternalObject(object); protect(internalObject); Object result = getUserValue(((EList<?>) internalObject.eGet(feature)).remove(index), feature); unprotect(internalObject); return result; } @Override public Object move(InternalEObject object, EStructuralFeature feature, int targetIndex, int sourceIndex) { feature = getInternalFeature(feature); FInternalObjectImpl internalObject = getInternalObject(object); protect(internalObject); Object result = getUserValue(((EList<?>) internalObject.eGet(feature)).move(targetIndex, sourceIndex), feature); unprotect(internalObject); return result; } @Override public void clear(InternalEObject object, EStructuralFeature feature) { feature = getInternalFeature(feature); FInternalObjectImpl internalObject = getInternalObject(object); protect(internalObject); ((EList<?>) internalObject.eGet(feature)).clear(); unprotect(internalObject); } @Override public Object[] toArray(InternalEObject object, EStructuralFeature feature) { feature = getInternalFeature(feature); Object[] array = ((EList<?>) getInternalObject(object).eGet(feature)).toArray(); Object[] result = new Object[array.length]; for (int i = 0; i < array.length; i++) { result[i] = getUserValue(array[i], feature); } return result; } @SuppressWarnings("unchecked") @Override public <T> T[] toArray(InternalEObject object, EStructuralFeature feature, T[] array) { feature = getInternalFeature(feature); Object[] values = ((EList<?>) getInternalObject(object).eGet(feature)).toArray(new Object[array.length]); Object[] result = new Object[array.length]; for (int i = 0; i < values.length; i++) { result[i] = getUserValue(values[i], feature); } return (T[]) result; } @Override public int hashCode(InternalEObject object, EStructuralFeature feature) { feature = getInternalFeature(feature); return getInternalObject(object).eGet(feature).hashCode(); } @Override public InternalEObject getContainer(InternalEObject object) { return (InternalEObject) getUserValue(getInternalObject(object).eContainer(), null); } @Override public EStructuralFeature getContainingFeature(InternalEObject object) { EStructuralFeature internalFeature = getInternalObject(object).eContainingFeature(); return ReflectiveMetaModelRegistry.instance.getRegularFeature(internalFeature); } @Override public EObject create(EClass eClass) { throw new UnsupportedOperationException(); } private boolean protect(FInternalObjectImpl object) { if (object != null) { Fragment fragment = object.getFragment(); if (fragment != null) { fragment.getFragmentedModel().protect(object.getFragment()); return true; } } return false; } private void unprotect(FInternalObjectImpl object) { if (object != null) { Fragment fragment = object.getFragment(); if (fragment != null) { fragment.getFragmentedModel().unprotect(object.getFragment()); } } } }